package yuhuibear.poat.object.pipe;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.sql.Timestamp;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import yuhuibear.poat.test.DatabaseTest;
import yuhuibear.poat.test.entity.Log;
import yuhuibear.poat.test.entity.User;
import yuhuibear.poat.test.entity.sub.PersonalDetail;
import yuhuibear.poat.test.entity.sub.UserLog;
import yuhuibear.poat.test.util.PoatTestSource;

import com.bgIntlgn.client.entity.privilege.Account;
import com.bgIntlgn.client.entity.privilege.Skill;
import com.bgIntlgn.client.entity.privilege.SkillBean;

/**
 * +
 * 
 * @author yuhuibear
 */
public class ObjectAccessPipeTest {

	private static POAT pm;

	private ObjectAccessPipe instance;

	public ObjectAccessPipeTest() {
	}

	@BeforeClass
	public static void setUpClass() throws Exception {
		pm = new POAT(new PoatTestSource(), "yuhuibear.poat.test.entity");
		System.out.println("scanned " + pm.scanEntity("com.bgIntlgn.client.entity") + " beans");
		System.out.println("mapped " + pm.mapAllEntities(true) + " beans");

		new DatabaseTest();
	}

	@AfterClass
	public static void tearDownClass() throws Exception {
	}

	@Before
	public void setUp() {
		try {
			instance = pm.getPipe();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@After
	public void tearDown() {
		try {
			instance.commit();
			instance.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Test of list method, of class ObjectAccessPipe.
	 */
	@Test
	public void testListClassOfTStringArrayObjectArray() throws Exception {
		Class<User> type = User.class;
		String[] conditions = new String[] { "User.id  < ?" };
		Object[] params = new Object[] { 5 };
		int expSize = 3;
		List<User> result = instance.list(type, conditions, params);
		assertEquals(result.size(), expSize);
		// >>>>>>>>>>>>>>>>>>page test
		instance.setPageLenth(2);
		instance.setPageNumber(0);
		expSize = 2;
		result = instance.list(type, conditions, params);
		assertEquals(result.size(), expSize);

		instance.setPageLenth(2);
		instance.setPageNumber(1);
		expSize = 1;
		result = instance.list(type, conditions, params);
		assertEquals(result.size(), expSize);

		expSize = 3;
		result = instance.list(type, conditions, params);
		assertEquals(result.size(), expSize);
		// <<<<<<<<<<<<<<<<<<<<<<page test
		conditions = new String[] { "users.id = ?" };
		params[0] = 5;
		result = instance.list(type, conditions, params);
		assertEquals(1, result.size());
		result = instance.list(User.class, null);

		@SuppressWarnings("unused")
		List<SkillBean> beanOfSkills = instance.list(SkillBean.class, new String[] { "SkillBean.skillName = ?" }, "aa");
		boolean catched = false;
		try {
			@SuppressWarnings("unused")
			List<Skill> skills = instance.list(Skill.class, new String[] { "Skill.Name= ?" }, "aa");
		} catch (yuhuibear.poat.exception.MissAttributesOfBean e) {
			catched = true;
		}
		assertTrue(catched);
	}

	@Test
	public void testGetClassOfTStringArrayObjectArray() throws Exception {
		System.out.println("<T> T get(Class<T> type, String[] conditions, Object... params)");
		String[] conditions = new String[] { "User.id  = ?" };
		Object[] params = new Object[] { 5 };
		User result = instance.get(User.class, conditions, params);

		assertTrue(result != null);

		conditions = new String[] { "UserLog.id  > ?" };
		params = new Object[] { 3 };
		UserLog result2 = instance.get(UserLog.class, conditions, params);

		assertTrue(result2 != null);
	}

	/**
	 * Test of list method, of class ObjectAccessPipe.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testListStringArrayClassOfTStringArrayObjectArray() throws Exception {
		System.out.println("list( String[] as,Class<T> type, String[] conditions, Object... params) throws Exception;");
		Class<UserLog> type = UserLog.class;

		String[] as = new String[] { "Log.id as id", "User.name as who_name", "Log.dsp as comment", "Log.time AS time" };
		String[] conditions = new String[] { "order by User.id", "Log.time > '2008-11-10'", "Log.ownerId = User.id" };

		int expSize = 10;
		List<UserLog> result = instance.list(as, type, conditions);
		if (result.size() < 1) {
			fail("exp: " + expSize + "\n" + "rsl: " + result.size());
		}
		for (int i = 0; i < result.size(); i++) {
			System.out.println("[i = " + i + "] , " + result.get(i));
		}
	}

	@Test
	public void testGetStringArrayClassOfTStringArrayObjectArray() throws Exception {
		System.out.println(" <T> T get(String[] as, Class<T> type, String[] conditions, Object... params)");

		Integer expSize = DatabaseTest.RECORD_CNT;
		Integer result = instance.get("count(User.id)", Integer.class, null);
		assertEquals(result, expSize);
	}

	/**
	 * Test of add method, of class ObjectAccessPipe.
	 */
	@Test
	public void testAddT() throws Exception {

		Log log = new Log();
		log.setDsp("in junit test : add(Object obj)");
		log.setName("yuhui");
		log.setTime(null);
		log.setOwnerId(3L);
		Object obj = log;
		instance.add(log);
		assertTrue(log.getId() > 0);
		System.out.println(log);

		User user = new User();
		user.setName("aaaaaaaaa");
		obj = user;
		instance.add(obj);
		assertTrue(user.getId() > 0);
		try {
			instance.add(null);
		} catch (java.lang.NullPointerException nulle) {
		}

		PersonalDetail rd = new PersonalDetail();
		rd.setI2d(user.getId());
		rd.setName("tttttttt");
		instance.add(rd);

		rd.setName(rd.getName() + "xxxxxxxxx");
		instance.update(rd);
	}

	/**
	 * Test of add method, of class ObjectAccessPipe.
	 */
	@Test
	public void testAddListOfT() throws Exception {

		List<Log> objs = new LinkedList<Log>();
		for (int i = 0; i < 200; i++) {
			Log log = new Log();
			log.setId(1000L + i * 10);
			log.setDsp("in junit test");
			log.setName("yuhui  " + i);
			log.setTime(new Date());
			log.setOwnerId(new Long(2));
			objs.add(log);
		}

		int expResult = objs.size();
		int result = instance.add(objs);
		assertTrue(expResult == result);
	}

	/**
	 * Test of update method, of class ObjectAccessPipe.
	 */
	@Test
	public void testUpdateT() throws Exception {

		// 100000;"yuhui";"in junit test";"2008-11-27";1
		List<Log> lst = instance.list(Log.class, null);
		Log obj = lst.get(0);
		obj.setDsp("in junit test");
		obj.setName("yuhui");
		obj.setTime((Date) (new Timestamp(new Date().getTime())));
		obj.setValue(22222);
		obj.setLongvalue(213212390999L);
		List<User> lst2 = instance.list(User.class, null);
		obj.setOwnerId(lst2.get(0).getId());
		instance.update(obj);
		Log rslt = instance.get(Log.class, new String[] { "Log.id = ?" }, obj.getId());
		assertEquals(obj.getId(), rslt.getId());
		assertEquals(obj.getDsp(), rslt.getDsp());
		assertEquals(obj.getName(), rslt.getName());
		assertEquals(obj.getTime(), rslt.getTime());
		assertEquals(obj.getOwnerId(), rslt.getOwnerId());
		assertEquals(obj.getValue(), rslt.getValue());
		assertEquals(obj.getLongvalue(), rslt.getLongvalue());

		Long aid = 5L;
		Account act = instance.get(Account.class, new String[] { "Account.id = " + aid });
		Integer cnt = act.getLogCnt() + 1;
		act.setLogCnt(cnt);

		instance.update(act);

		Account act2 = instance.get(Account.class, new String[] { "Account.id = " + aid });
		assertEquals(act2.getLogCnt(), cnt);
	}

	/**
	 * Test of update method, of class ObjectAccessPipe.
	 */
	@Test
	public void testUpdateClassOfQStringArrayStringArrayObjectArray() throws Exception {
		String[] attrs = new String[] { "Log.dsp  =  ?", "Log.id = Log.id + 10000000", "Log.name = ?" };
		String[] conditions = new String[] { "Log.ownerId = User.id", "User.id = ?" };

		int cnt = instance.update(Log.class, attrs, conditions, "hhhhhh", "nameupdate", 1);

		List<Log> lst = pm.getPipe().list(Log.class, new String[] { "Log.id > 10000000" });
		if (lst.size() < 0) {
			fail("updated : " + cnt + ", effected : " + lst.size());
		}

		cnt = instance.update(Log.class, new String[] { "Log.dsp  =  ?", "Log.id = id + 10000000" },
				new String[] { "*" }, "update all");
	}

	/**
	 * Test of delete method, of class ObjectAccessPipe.
	 */
	@Test
	public void testDeleteT() throws Exception {
		Long cnt = instance.get("count(Log.id)", Long.class, null);
		Log old = new Log();
		// 100000;"yuhui";"in junit test";"2008-11-27";1
		old.setId(10000005L);
		old.setDsp("in junit test");
		old.setName("yuhui");
		old.setTime(new Date());
		old.setOwnerId(1L);

		instance = pm.getPipe();
		instance.delete(old);

		Long rslt = instance.get("count(Log.id)", Long.class, null);
		assertTrue(cnt - rslt == 1);
	}

	/**
	 * Test of delete method, of class ObjectAccessPipe.
	 */
	@Test
	public void testDeleteListOfT() throws Exception {

		List<Log> lst = new LinkedList<Log>();
		for (int i = 0; i < 2; i++) {
			Log log = new Log();
			log.setId(1000L + i * 10);
			log.setDsp("in junit test");
			log.setName("yuhui  " + i);
			log.setTime(new Date());
			log.setOwnerId(new Long(i));
			lst.add(log);
		}

		int expResult = lst.size();
		int result = instance.delete(lst);
		if (result != expResult) {
			fail("exp: " + expResult + "\n" + "rsl: " + result);
		}
	}

	/**
	 * Test of delete method, of class ObjectAccessPipe.
	 */
	@Test
	public void testDeleteClassOfTStringArrayObjectArray() throws Exception {
		String[] conditions = new String[] { "Log.id > ?" };
		Object[] params = new Object[] { 5 };
		int result = instance.delete(Log.class, conditions, params);
		assertTrue(result > 0);
		boolean catched = false;
		try {
			instance.delete(Log.class, null);
		} catch (Exception e) {
			catched = true;
		}
		assertTrue(catched);
	}
}
